package com.giscloud.amp.service.auth.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.giscloud.amp.dao.AmpGetDataMeansMapper;
import com.giscloud.amp.dao.AmpRoleMapper;
import com.giscloud.amp.dao.AmpStaffDataMapper;
import com.giscloud.amp.entity.*;
import com.giscloud.amp.entity.dto.AmpGetDataMeansDTO;
import com.giscloud.amp.entity.dto.AmpStaffDataDTO;
import com.giscloud.amp.entity.dto.AmpStaffOrgDTO;
import com.giscloud.amp.entity.vo.AmpRoleVO;
import com.giscloud.amp.entity.vo.AmpStaffDataVO;
import com.giscloud.amp.entity.vo.AmpStaffSystemOrgVO;
import com.giscloud.amp.service.auth.AmpStaffDataService;
import com.giscloud.commons.model.Result;
import com.giscloud.commons.sql.Specification;
import com.giscloud.commons.utils.FastJsonUtils;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author:gxd
 * @Description:全局数据权限(城市)服务
 * @Date: 9:20 2018/12/5
 * @Modified By:
 */
@Service("ampStaffDataService")
public class AmpStaffDataServiceImpl implements AmpStaffDataService {
    private final static Logger log = LoggerFactory.getLogger(AmpStaffDataServiceImpl.class);
    @Autowired
    private AmpStaffDataMapper ampStaffDataMapper;
    @Autowired
    private AmpGetDataMeansMapper ampGetDataMeansMapper;
    @Autowired
    private AmpRoleMapper ampRoleMapper;

    @Override
    public List<Map> findCityList(AmpStaffDataDTO ampStaffDataDTO) {
        log.debug("findCityList入参："+ FastJsonUtils.toJSONString(ampStaffDataDTO));
        AmpStaffDataExample ampStaffDataExample = new AmpStaffDataExample();
        AmpStaffDataExample.Criteria criteria = ampStaffDataExample.createCriteria();
        if(ampStaffDataDTO.getSystemId() != null) {
            criteria.andSystemIdEqualTo(ampStaffDataDTO.getSystemId());
        }
        //1、获取用户在用的角色
        if(CollectionUtil.isNotEmpty(ampStaffDataDTO.getRolesId())) {
            AmpRoleExample ampRoleExample = new AmpRoleExample();
            AmpRoleExample.Criteria ampRoleCriteria = ampRoleExample.createCriteria();
            ampRoleCriteria.andRoleIdIn(ampStaffDataDTO.getRolesId());
            ampRoleCriteria.andStatusCdEqualTo((short) 1);
            List<AmpRoleVO> ampRoleVOS = ampRoleMapper.selectByExample(ampRoleExample);
            List<Long> roles = new ArrayList<>();
            for (AmpRoleVO ampRoleVO : ampRoleVOS) {
                roles.add(ampRoleVO.getRoleId());
            }
            ampStaffDataDTO.setRolesId(roles);
        }
        //2、根据角色、或者用户来查询数据权限
        List<AmpStaffDataVO> ampStaffData = ampStaffDataMapper.selectAmpStaffData(ampStaffDataDTO);
        if(ampStaffData.size()>0){
            //多条数据权限，以下拼装where条件
            //过滤条件
            StringBuffer condition = new StringBuffer(10);
            String valueMin = "",valueMax = "";
            Specification specification = null;
            for (AmpStaffDataVO ampStaffDatum : ampStaffData) {
                if(ampStaffDatum.getGetDataValueMin() == null){
                    valueMin = "";
                }
                if(ampStaffDatum.getGetDataValueMax() == null){
                    valueMax  ="";
                }
                condition.append(" ( ");
                specification = new Specification();
                condition.append(specification.buildWhereSql(ampStaffDatum.getColumnName(),
                        ampStaffDatum.getGetDataRule(),
                        ampStaffDatum.getGetDataValue(),
                        valueMin,valueMax).toString()).
                        append(" and ").append(" area_level = ").
                        append(ampStaffDatum.getDataType()).
                        append(" ) ").append(" or ");
            }
            Map paramMap = Maps.newHashMapWithExpectedSize(10);
            //查询城市
            paramMap.put("systemId",ampStaffDataDTO.getSystemId());
            paramMap.put("key",ampStaffDataDTO.getKey());
            paramMap.put("condition",condition.delete(condition.length()-4,condition.length()).toString());
            return ampStaffDataMapper.selectAreas(paramMap);
        }else{
            return new ArrayList<>();
        }
    }
    private static String[] union(String[] arr1, String[] arr2) {
        Set<String> set = new HashSet<String>();
        for (String str : arr1) {
            set.add(str);
        }
        for (String str : arr2) {
            set.add(str);
        }
        String[] result = {};
        return set.toArray(result);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
    public Result editDataAuth(AmpGetDataMeansDTO ampGetDataMeansDTO) {
        try{
            AmpStaffDataExample ampStaffDataExample = new AmpStaffDataExample();
            AmpStaffDataExample.Criteria criteria = ampStaffDataExample.createCriteria();
            criteria.andSystemIdEqualTo(ampGetDataMeansDTO.getSystemId());
            criteria.andObjectIdEqualTo(ampGetDataMeansDTO.getObjectId());
            criteria.andObjectTypeEqualTo(ampGetDataMeansDTO.getObjectType());
            criteria.andStatusCdEqualTo((short) 1);
            criteria.andDataTypeEqualTo(ampGetDataMeansDTO.getDataType());
            List<AmpStaffData> ampStaffDataList = ampStaffDataMapper.selectByExample(ampStaffDataExample);
            //批量启用
            if(ampGetDataMeansDTO.getStatusCd().equals("1")){
                if(CollectionUtil.isNotEmpty(ampStaffDataList)){
                    AmpStaffData ampStaffData = ampStaffDataList.get(0);
                    Long getDataMeansId = ampStaffData.getGetDataMeansId();
                    AmpGetDataMeansExample example = new AmpGetDataMeansExample();
                    example.createCriteria().andStatusCdEqualTo((short) 1).andGetDataMeansIdEqualTo(getDataMeansId);
                    List<AmpGetDataMeans> ampGetDataMeans = ampGetDataMeansMapper.selectByExample(example);
                    String getDataValue1 = ampGetDataMeansDTO.getGetDataValue();
                    String getDataValue2 = ampGetDataMeans.get(0).getGetDataValue();
                    AmpGetDataMeans getDataMeans = new AmpGetDataMeans();
                    BeanUtil.copyProperties(ampGetDataMeansDTO,getDataMeans);
                    //查询value值，取合集保存
                    getDataMeans.setGetDataValue(StringUtils.join(union(getDataValue1.split(","),getDataValue2.split(",")), ","));
                    AmpGetDataMeansExample ampGetDataMeansExample = new AmpGetDataMeansExample();
                    ampGetDataMeansExample.createCriteria().andGetDataMeansIdEqualTo(getDataMeansId);
                    ampGetDataMeansMapper.updateByExampleSelective(getDataMeans,ampGetDataMeansExample);
                }else{
                    AmpGetDataMeans ampGetDataMeans = new AmpGetDataMeans();
                    BeanUtil.copyProperties(ampGetDataMeansDTO, ampGetDataMeans);
                    ampGetDataMeans.setOpreateStaffId(ampGetDataMeansDTO.getStaffId());
                    ampGetDataMeans.setVersion(new Date());
                    ampGetDataMeans.setStatusCd((short) 1);
                    ampGetDataMeans.setCreatedStaffId(ampGetDataMeansDTO.getStaffId());
                    ampGetDataMeans.setCreatedDt(new Date());
                    ampGetDataMeansMapper.insertSelective(ampGetDataMeans);
                    if (ampGetDataMeans.getGetDataMeansId() != null) {
                        AmpStaffData ampStaffData = new AmpStaffData();
                        ampStaffData.setCreatedDt(new Date());
                        ampStaffData.setVersion(new Date());
                        ampStaffData.setStatusCd((short) 1);
                        ampStaffData.setCreatedStaffId(ampGetDataMeansDTO.getStaffId());
                        ampStaffData.setSystemId(ampGetDataMeansDTO.getSystemId());
                        ampStaffData.setObjectId(ampGetDataMeansDTO.getObjectId());
                        ampStaffData.setObjectType(ampGetDataMeansDTO.getObjectType());
                        ampStaffData.setDataType(ampGetDataMeansDTO.getDataType());
                        ampStaffData.setGetDataMeansId(ampGetDataMeans.getGetDataMeansId());
                        ampStaffDataMapper.insertSelective(ampStaffData);
                    }else{
                        return Result.error(-1,"保存失败");
                    }
                }
            }else{
                //批量停用
                if(CollectionUtil.isNotEmpty(ampStaffDataList)){
                    AmpStaffData ampStaffData = ampStaffDataList.get(0);
                    Long getDataMeansId = ampStaffData.getGetDataMeansId();
                    AmpGetDataMeansExample example = new AmpGetDataMeansExample();
                    example.createCriteria().andStatusCdEqualTo((short) 1).andGetDataMeansIdEqualTo(getDataMeansId);
                    List<AmpGetDataMeans> ampGetDataMeans = ampGetDataMeansMapper.selectByExample(example);
                    String getDataValue1 = ampGetDataMeansDTO.getGetDataValue();
                    String getDataValue2 = ampGetDataMeans.get(0).getGetDataValue();
                    List<String> list = Arrays.asList(getDataValue2.split(","));
                    List<String> arrayList = new ArrayList<>(list);//转换为ArrayLsit调用相关的remove方法
                    String []getDataValue1s = getDataValue1.split(",");
                    for (String dataValue1 : getDataValue1s) {
                        arrayList.remove(dataValue1);
                    }
                    AmpGetDataMeans getDataMeans = new AmpGetDataMeans();
                    BeanUtil.copyProperties(ampGetDataMeansDTO,getDataMeans);
                    if(arrayList.size() == 0){
                        getDataMeans.setStatusCd((short) 2);
                        AmpStaffDataExample staffDataExample = new AmpStaffDataExample();
                        AmpStaffDataExample.Criteria ampStaffDataCriteria = staffDataExample.createCriteria();
                        ampStaffDataCriteria.andSystemIdEqualTo(ampGetDataMeansDTO.getSystemId());
                        ampStaffDataCriteria.andObjectIdEqualTo(ampGetDataMeansDTO.getObjectId());
                        ampStaffDataCriteria.andObjectTypeEqualTo(ampGetDataMeansDTO.getObjectType());
                        ampStaffDataCriteria.andDataTypeEqualTo(ampGetDataMeansDTO.getDataType());
                        AmpStaffData staffData = new AmpStaffData();
                        staffData.setStatusCd((short) 2);
                        staffData.setVersion(new Date());
                        ampStaffDataMapper.updateByExampleSelective(staffData, staffDataExample);
                    }else {
                        getDataMeans.setStatusCd((short) 1);
                    }
                    getDataMeans.setGetDataValue(StringUtils.join(arrayList, ","));
                    AmpGetDataMeansExample ampGetDataMeansExample = new AmpGetDataMeansExample();
                    ampGetDataMeansExample.createCriteria().andGetDataMeansIdEqualTo(ampStaffDataList.get(0).getGetDataMeansId());
                    ampGetDataMeansMapper.updateByExampleSelective(getDataMeans,ampGetDataMeansExample);
                }
            }

        }catch (Exception e){
            return Result.error(-1,"保存失败");
        }
        return Result.success("保存成功");
    }

    @Override
    public List<Map> getObjectDataIds(AmpGetDataMeansDTO ampGetDataMeansDTO) {
        AmpStaffDataDTO ampStaffDataDTO = new AmpStaffDataDTO();
        ampStaffDataDTO.setSystemId(ampGetDataMeansDTO.getSystemId());
        ampStaffDataDTO.setTableName(ampGetDataMeansDTO.getTableName());
        ampStaffDataDTO.setAreaLevel(ampGetDataMeansDTO.getDataType());
        List<Long> rolds = new ArrayList<>();
        if(ampGetDataMeansDTO.getObjectType().equals("2")){
            rolds.add(ampGetDataMeansDTO.getObjectId());
            ampStaffDataDTO.setStaffId(-1L);
        }else{
            ampStaffDataDTO.setStaffId(ampGetDataMeansDTO.getObjectId());
        }
        ampStaffDataDTO.setRolesId(rolds);
        return findCityList(ampStaffDataDTO);
    }

    /**
     * 单个启用、停用数据权限
     * @param ampGetDataMeansDTO
     * @return
     */
   @Override
    @Transactional(propagation= Propagation.REQUIRED, rollbackFor=Exception.class)
    public Result enableDataAuth(AmpGetDataMeansDTO ampGetDataMeansDTO) {
        AmpStaffDataExample ampStaffDataExample = new AmpStaffDataExample();
        AmpStaffDataExample.Criteria criteria = ampStaffDataExample.createCriteria();
        criteria.andSystemIdEqualTo(ampGetDataMeansDTO.getSystemId());
        criteria.andObjectIdEqualTo(ampGetDataMeansDTO.getObjectId());
        criteria.andObjectTypeEqualTo(ampGetDataMeansDTO.getObjectType());
        criteria.andDataTypeEqualTo(ampGetDataMeansDTO.getDataType());
        List<AmpStaffData> ampStaffDataList = ampStaffDataMapper.selectByExample(ampStaffDataExample);
        //启用的话
        if("1".equals(ampGetDataMeansDTO.getStatusCd())){
            if(CollectionUtil.isEmpty(ampStaffDataList)){
                //插入
                AmpGetDataMeans ampGetDataMeans = new AmpGetDataMeans();
                BeanUtil.copyProperties(ampGetDataMeansDTO, ampGetDataMeans);
                ampGetDataMeans.setOpreateStaffId(ampGetDataMeansDTO.getStaffId());
                ampGetDataMeans.setVersion(new Date());
                ampGetDataMeans.setStatusCd((short) 1);
                ampGetDataMeans.setCreatedStaffId(ampGetDataMeansDTO.getStaffId());
                ampGetDataMeans.setCreatedDt(new Date());
                ampGetDataMeansMapper.insertSelective(ampGetDataMeans);
                if (ampGetDataMeans.getGetDataMeansId() != null) {
                    AmpStaffData ampStaffData = new AmpStaffData();
                    ampStaffData.setCreatedDt(new Date());
                    ampStaffData.setVersion(new Date());
                    ampStaffData.setStatusCd((short) 1);
                    ampStaffData.setCreatedStaffId(ampGetDataMeansDTO.getStaffId());
                    ampStaffData.setSystemId(ampGetDataMeansDTO.getSystemId());
                    ampStaffData.setObjectId(ampGetDataMeansDTO.getObjectId());
                    ampStaffData.setObjectType(ampGetDataMeansDTO.getObjectType());
                    ampStaffData.setDataType(ampGetDataMeansDTO.getDataType());
                    ampStaffData.setGetDataMeansId(ampGetDataMeans.getGetDataMeansId());
                    ampStaffDataMapper.insertSelective(ampStaffData);
                }else{
                    return Result.error(-1,"保存失败");
                }
            }else {
                AmpStaffData ampStaffData = ampStaffDataList.get(0);
                if(ampStaffDataList.get(0).getStatusCd() == 2) {
                    AmpStaffDataExample example = new AmpStaffDataExample();
                    AmpStaffDataExample.Criteria ampStaffDataCriteria = example.createCriteria();
                    ampStaffDataCriteria.andSystemIdEqualTo(ampGetDataMeansDTO.getSystemId());
                    ampStaffDataCriteria.andObjectIdEqualTo(ampGetDataMeansDTO.getObjectId());
                    ampStaffDataCriteria.andObjectTypeEqualTo(ampGetDataMeansDTO.getObjectType());
                    ampStaffDataCriteria.andDataTypeEqualTo(ampGetDataMeansDTO.getDataType());
                    AmpStaffData staffData = new AmpStaffData();
                    staffData.setStatusCd((short) 1);
                    staffData.setVersion(new Date());
                    ampStaffDataMapper.updateByExampleSelective(staffData, example);
                    AmpGetDataMeans getDataMeans = new AmpGetDataMeans();
                    BeanUtil.copyProperties(ampGetDataMeansDTO,getDataMeans);
                    getDataMeans.setGetDataValue(ampGetDataMeansDTO.getGetDataValue().toString());
                    AmpGetDataMeansExample ampGetDataMeansExample = new AmpGetDataMeansExample();
                    ampGetDataMeansExample.createCriteria().andGetDataMeansIdEqualTo(ampStaffData.getGetDataMeansId());
                    ampGetDataMeansMapper.updateByExampleSelective(getDataMeans,ampGetDataMeansExample);
                }else{
                    Long getDataMeansId = ampStaffData.getGetDataMeansId();
                    AmpGetDataMeansExample example = new AmpGetDataMeansExample();
                    example.createCriteria().andStatusCdEqualTo((short) 1).andGetDataMeansIdEqualTo(getDataMeansId);
                    List<AmpGetDataMeans> ampGetDataMeans = ampGetDataMeansMapper.selectByExample(example);
                    String getDataValue = ampGetDataMeans.get(0).getGetDataValue();
                    String[] union = union(new String[]{ampGetDataMeansDTO.getGetDataValue()}, getDataValue.split(","));
                    AmpGetDataMeans getDataMeans = new AmpGetDataMeans();
                    BeanUtil.copyProperties(ampGetDataMeansDTO,getDataMeans);
                    getDataMeans.setGetDataValue(StringUtils.join(union, ","));
                    AmpGetDataMeansExample ampGetDataMeansExample = new AmpGetDataMeansExample();
                    ampGetDataMeansExample.createCriteria().andGetDataMeansIdEqualTo(ampStaffDataList.get(0).getGetDataMeansId());
                    ampGetDataMeansMapper.updateByExampleSelective(getDataMeans,ampGetDataMeansExample);
                }
            }
        }else{
            AmpStaffData ampStaffData = ampStaffDataList.get(0);
            Long getDataMeansId = ampStaffData.getGetDataMeansId();
            AmpGetDataMeansExample example = new AmpGetDataMeansExample();
            example.createCriteria().andStatusCdEqualTo((short) 1).andGetDataMeansIdEqualTo(getDataMeansId);
            List<AmpGetDataMeans> ampGetDataMeans = ampGetDataMeansMapper.selectByExample(example);

            String getDataValue = ampGetDataMeans.get(0).getGetDataValue();
            String getDataValues[] = getDataValue.split(",");
            List<String> list = Arrays.asList(getDataValues);
            List<String> arrayList = new ArrayList<>(list);//转换为ArrayLsit调用相关的remove方法
            arrayList.remove(ampGetDataMeansDTO.getGetDataValue());
            AmpGetDataMeans getDataMeans = new AmpGetDataMeans();
            BeanUtil.copyProperties(ampGetDataMeansDTO,getDataMeans);
            if(arrayList.size() == 0){
                getDataMeans.setStatusCd((short) 2);
                AmpStaffDataExample staffDataExample = new AmpStaffDataExample();
                AmpStaffDataExample.Criteria ampStaffDataCriteria = staffDataExample.createCriteria();
                ampStaffDataCriteria.andSystemIdEqualTo(ampGetDataMeansDTO.getSystemId());
                ampStaffDataCriteria.andObjectIdEqualTo(ampGetDataMeansDTO.getObjectId());
                ampStaffDataCriteria.andObjectTypeEqualTo(ampGetDataMeansDTO.getObjectType());
                ampStaffDataCriteria.andDataTypeEqualTo(ampGetDataMeansDTO.getDataType());
                AmpStaffData staffData = new AmpStaffData();
                staffData.setStatusCd((short) 2);
                staffData.setVersion(new Date());
                ampStaffDataMapper.updateByExampleSelective(staffData, staffDataExample);
            }else {
                getDataMeans.setStatusCd((short) 1);
            }
            getDataMeans.setGetDataValue(StringUtils.join(arrayList, ","));
            AmpGetDataMeansExample ampGetDataMeansExample = new AmpGetDataMeansExample();
            ampGetDataMeansExample.createCriteria().andGetDataMeansIdEqualTo(ampStaffDataList.get(0).getGetDataMeansId());
            ampGetDataMeansMapper.updateByExampleSelective(getDataMeans,ampGetDataMeansExample);
        }
        return Result.success("保存成功");
    }

    @Override
    public List<AmpStaffSystemOrgVO> getOrgByStaffId(AmpStaffOrgDTO ampStaffOrgDTO) {
        return ampStaffDataMapper.getOrgByStaffId(ampStaffOrgDTO);
    }

}
